#ifndef BLOQUE_H_
#define BLOQUE_H_

#include <list>
#include "Componente.h"
#include "Clave.h"

namespace Toolkit
{

class Bloque : public Componente
{
public:
    Bloque(const unsigned long int &tamanoBloque, const TipoSerializacion&, const bool &ordenado = false);

    virtual ~Bloque();
    
    void serializar(stringstream&) const;
    void hidratar(stringstream&);

    /**
	 * Si hay suficiente espacio, se agrega el bloque indicado
	 * a los componentes del bloque. Si no se devuelve false.
	 * */
    bool agregar(Componente&, const Clave&);
    
    /**
	 * Retira del bloque el elemento cuya clave es pasada y lo retorna.
	 * Si no se encuentra el elemento, se devuelve NULL.
	 * */
    Componente* remover(const Clave&);
    
    /**
     * Devuelve el elemento del bloque con la clave pasada,
     * o NULL de no encontrarlo.
     * */
    Componente* buscar(const Clave&);
    
    /**
     * Devuelve el espacio, en bytes, que queda libre en el bloque.
     * Esto es, se podra agregar al bloque cualquier elemento
     * cuya serializacion tenga un tamano menor al devuelto.
     * */
    virtual unsigned long int espacioLibre() const;    
    /**
     * Devuelve el tamano del bloque, en bytes.
     * */
    unsigned long int getTamanoBloque() const;
    
    /**
	 * Devuelve true, si la clave mas grande de los elementos del 
	 * bloque es menor a la clave pasada.
	 * */
    virtual bool operator < (const Clave&) const;
    /**
     * Devuelve true si la clave pasada coincide con la mayor clave
     * de los elementos del bloque.
     * */
    virtual bool operator == (const Clave&) const;

    virtual int cantElementos() const;

    Componente* pop();

    virtual char getTipo() const;
	
private:
    /* Tamano en bytes del identificador que se coloca en la serializacion antes
     * de cada elemento.*/    
    static const short int TAMANO_ID_TEXTO = 2;//TODO ver cuanto vale
    unsigned long int tamanoBloque;
    unsigned long int espacioOcupado;
    list<Componente*> componentes; //TODO esto no sirve
    
    void serializacionFinalComponente(const Componente&, stringstream&) const;


protected:
    bool ordenado;
};

}

#endif /* BLOQUE_H_ */
